package cn.com.cifi.mars.service.impl;

import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeSet;
import java.util.stream.Collectors;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import cn.com.cifi.mars.bean.vo.supply.SumValueVO;
import cn.com.cifi.mars.constant.Constants;
import cn.com.cifi.mars.constant.IsDeleteEnum;
import cn.com.cifi.mars.constant.OrgTypeEunm;
import cn.com.cifi.mars.constant.SalyTypeEnum;
import cn.com.cifi.mars.constant.VersionTypeEunm;
import cn.com.cifi.mars.entity.SupplyPlanVersionDetail;
import cn.com.cifi.mars.mapper.mars.SupplyPlanVersionDetailMapper;
import cn.com.cifi.mars.service.SupplyPlanExportService;
import cn.com.cifi.mars.util.DateUtils;
import cn.com.cifi.mars.util.LocalDateTimeUtils;
import cn.com.cifi.mars.util.StrUtils;
import cn.com.cifi.mars.util.UUIDUtils;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
public class SupplyPlanServiceExportImpl implements SupplyPlanExportService{

	@Autowired
	private SupplyPlanVersionDetailMapper supplyPlanVersionDetailMapper;
	
	List<SupplyPlanVersionDetail> parentList = Collections.synchronizedList(new ArrayList<>());
	
	@Override
	public List<SupplyPlanVersionDetail> collectDetailList(List<SupplyPlanVersionDetail> alist,String versionType,String code, String year, String month){
		parentList = Collections.synchronizedList(new ArrayList<>());
		List<SupplyPlanVersionDetail> allList = getTempList(alist);
		if(StrUtils.isNotEmpty(month)) {
			month = year + "-" + month;
		}
		List<SupplyPlanVersionDetail> dataList = Collections.synchronizedList(new ArrayList<>());
		List<SupplyPlanVersionDetail> resList = Collections.synchronizedList(new ArrayList<>());
		List<SupplyPlanVersionDetail> lastList = Collections.synchronizedList(new ArrayList<>());
		if(CollectionUtils.isNotEmpty(allList)) {
			for(SupplyPlanVersionDetail allDetail : allList) {
				LocalDateTime supplyDate = allDetail.getSupplyDate();
				LocalDateTime supplyDateActual = allDetail.getSupplyTimeVirtual() == null ? allDetail.getSupplyDateActual() : allDetail.getSupplyTimeVirtual();
				if(StrUtils.isEmpty(month)) {
					if(planIsSameYear(supplyDate,year) || actualIsSameYear(supplyDateActual,year)) {
						dataList.add(allDetail);
					}
				}else {
					if(planIsSameMonth(supplyDate,month) || actualIsSameMonth(supplyDateActual,month)) {
						dataList.add(allDetail);
					}
				}
			}
			resList.addAll(dataList);
			//获取所有子级
			for(SupplyPlanVersionDetail data : dataList) {
				List<SupplyPlanVersionDetail>  list = getChildList(allList,data.getId());
				resList.addAll(list);
			}
			//获取所有父级
			for(SupplyPlanVersionDetail data : dataList) {
				List<SupplyPlanVersionDetail>  list = getParentList(allList,data.getPid());
				resList.addAll(list);
			}
			//去重
			lastList = resList.stream().collect(
	                Collectors.collectingAndThen(
	                        Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(SupplyPlanVersionDetail::getId))), ArrayList::new)
	        );
			handleData(lastList,year,month);
			//清空存在子级的数据
			emptyData(lastList);
			//数据汇总
			collectData(lastList);
		}
		return handleBuildData(lastList,year,month);
	}
	
	public List<SupplyPlanVersionDetail> getTempList(List<SupplyPlanVersionDetail> alllist) {
		List<SupplyPlanVersionDetail> dataList = Collections.synchronizedList(new ArrayList<>());
		for(SupplyPlanVersionDetail de : alllist) {
			try {
				dataList.add((SupplyPlanVersionDetail) BeanUtils.cloneBean(de));
			} catch (IllegalAccessException | InstantiationException | InvocationTargetException
					| NoSuchMethodException e) {
				log.error("###### errorMsg: ", e);
			}
		}
		return dataList;
	}
	
	private void handleData(List<SupplyPlanVersionDetail> resdataList,String year,String month) {
		if(StrUtils.isNotEmpty(month)) {
			year = "";
		}
		List<String> planIds = new ArrayList<>();
		List<String> actualIds = new ArrayList<>();
		List<String> yearOverIds = new ArrayList<>();
		List<String> monthOverIds = new ArrayList<>();
		for(SupplyPlanVersionDetail obj : resdataList) {
			LocalDateTime supplyDate = obj.getSupplyDate();
			LocalDateTime supplyDateActual = obj.getSupplyDateActual() == null ? obj.getSupplyTimeVirtual() : obj.getSupplyDateActual();
			if(supplyDate != null) {
				if(StrUtils.isNotEmpty(year)) {
					String yearStr = String.valueOf(supplyDate.getYear());
					if(!yearStr.equals(year)) {
						planIds.add(obj.getId());
					}
				}
				if(StrUtils.isNotEmpty(month)) {
					String monthStr = LocalDateTimeUtils.formatTime(supplyDate, "yyyy-MM");
					if(!monthStr.equals(month)) {
						planIds.add(obj.getId());
					}
				}
			}
			
			if(supplyDateActual != null) {
				if(StrUtils.isNotEmpty(year)) {
					String yearStr = String.valueOf(supplyDateActual.getYear());
					if(!yearStr.equals(year)) {
						actualIds.add(obj.getId());
					}
					if(supplyDateActual.getYear() < Integer.parseInt(year)) {
						yearOverIds.add(obj.getId());
					}
				}
				if(StrUtils.isNotEmpty(month)) {
					String monthStr = LocalDateTimeUtils.formatTime(supplyDateActual, "yyyy-MM");
					if(!monthStr.equals(month)) {
						actualIds.add(obj.getId());
					}
					
					int yearMonth = LocalDateTimeUtils.toIntYearMonth(Integer.parseInt(month.split("-")[0]), Integer.parseInt(month.split("-")[1]));
					int actualYearMonth = LocalDateTimeUtils.toIntYearMonth(supplyDateActual.getYear(),supplyDateActual.getMonthValue());
					if(actualYearMonth < yearMonth) {
						monthOverIds.add(obj.getId());
					}
				}
			}
		}		
		
		for(String str : planIds) {
			List<SupplyPlanVersionDetail> list = getChildList(resdataList,str);
			for(SupplyPlanVersionDetail obj : list) {
				for(SupplyPlanVersionDetail resData : resdataList) {
					if(resData.getId().equals(obj.getId())) {
						cleanPlanData(resData);
					}
				}
			}
		}
		
		for(String str : actualIds) {
			List<SupplyPlanVersionDetail> list = getChildList(resdataList,str);
			for(SupplyPlanVersionDetail obj : list) {
				for(SupplyPlanVersionDetail resData : resdataList) {
					if(resData.getId().equals(obj.getId())) {
						cleanActualData(resData);
					}
				}
			}
		}
		
		
		for(String str : yearOverIds) { 
			List<SupplyPlanVersionDetail> list = getChildList(resdataList,str);
			for(SupplyPlanVersionDetail obj : list) {
				for(SupplyPlanVersionDetail resData : resdataList) {
					if(resData.getId().equals(obj.getId())) {
						cleanPlanData(resData);
					}
				}
			}
		}
		for(String str : monthOverIds) { 
			List<SupplyPlanVersionDetail> list = getChildList(resdataList,str);
			for(SupplyPlanVersionDetail obj : list) {
				for(SupplyPlanVersionDetail resData : resdataList) {
					if(resData.getId().equals(obj.getId())) {
						cleanPlanData(resData);
					}
				}
			}
		}
	}
	
	private boolean planIsSameYear(LocalDateTime supplyDate,String year) {
		return supplyDate != null && year.equals(supplyDate.getYear()+"");
	}
	
	private boolean actualIsSameYear(LocalDateTime supplyDateActual,String year) {
		return supplyDateActual != null && year.equals(supplyDateActual.getYear()+"");
	}
	
	private boolean planIsSameMonth(LocalDateTime supplyDate,String month) {
		if(supplyDate != null) {
			String monthDate = LocalDateTimeUtils.formatTime(supplyDate,DateUtils.DATE_JFP_STR);
			return month.equals(monthDate);
		}
		return false;
	}
	
	private boolean actualIsSameMonth(LocalDateTime supplyDateActual,String month) {
		if(supplyDateActual != null) {
			String monthDate = LocalDateTimeUtils.formatTime(supplyDateActual,DateUtils.DATE_JFP_STR);
			return month.equals(monthDate);
		}
		return false;
	}
	
	private void cleanActualData(SupplyPlanVersionDetail resData) {
		resData.setRoomNumActual(null);
		resData.setParkingNumActual(null);
		resData.setAreaActual(null);
		resData.setAveragePriceHouseActual(null);
		resData.setAveragePriceParkingActual(null);
		resData.setHouseCommodityValueActual(null);
		resData.setNotCommodityValueActual(null);
		resData.setCommodityValueActual(null);
	}
	
	private void cleanPlanData(SupplyPlanVersionDetail resData) {
		resData.setNum(null);
		resData.setRoomNum(null);
		resData.setParkingNum(null);
		resData.setCommodityValue(null);
		resData.setHouseCommodityValue(null);
		resData.setNotCommodityValue(null);
		resData.setAveragePrice(null);
		resData.setAveragePriceParking(null);
		resData.setAveragePriceHouse(null);
		resData.setSaleArea(null);
	}
	
	public List<SupplyPlanVersionDetail> getChildList(List<SupplyPlanVersionDetail> allList,String pId){
		List<SupplyPlanVersionDetail> dataList = Collections.synchronizedList(new ArrayList<>());
		if(CollectionUtils.isNotEmpty(allList)) {
			for(SupplyPlanVersionDetail allDetail : allList) {
				if(allDetail.getPid().equals(pId) || allDetail.getId().equals(pId)) {
					dataList.add(allDetail);
				}
			}
		}
		return dataList;
	}
	
	public List<SupplyPlanVersionDetail> getParentList(List<SupplyPlanVersionDetail> allList,String id){
		if(CollectionUtils.isNotEmpty(allList)) {
			for(SupplyPlanVersionDetail allDetail : allList) {
				// 判断是否存在父节点
				if(allDetail.getId().equals(id)) {
					getParentList(allList,allDetail.getPid());
					parentList.add(allDetail);
				}
			}
		}
		return parentList;
	}
	
	@Override
	public List<SupplyPlanVersionDetail> collectSupplyPlanVersionDetailList(String versionType, String versionId) {
		List<SupplyPlanVersionDetail> dataList = Collections.synchronizedList(new ArrayList<>());
		List<SupplyPlanVersionDetail> lastList = Collections.synchronizedList(new ArrayList<>());
		List<SupplyPlanVersionDetail> detailList = supplyPlanVersionDetailMapper.selectByVersionId(versionId, IsDeleteEnum.NO.getKey());
		if(CollectionUtils.isNotEmpty(detailList)) {
			//投资版处理
			if(versionType.equals(VersionTypeEunm.INVESTMENT.getKey())) {
				dataList = handleInvestment(detailList);
			}else {
				dataList = detailList;
			}
			//处理显示数据（经营方式为可租和不可租售数据不显示）
			handleShowData(dataList,lastList);
			//清空存在子级的数据
			emptyData(lastList);
			//数据汇总
			collectData(lastList);
		}
		return lastList;
	}
	
	
	private List<SupplyPlanVersionDetail> handleBuildData(List<SupplyPlanVersionDetail> dataList,String year,String month) {
		if(StrUtils.isNotEmpty(month)) {
			if(CollectionUtils.isEmpty(dataList)) {
				return dataList;
			}
			List<SupplyPlanVersionDetail> lastList = getTempList(dataList);
			List<String> monthOverIds = new ArrayList<>();
			String versionId = "";
			 List<SupplyPlanVersionDetail> list = Collections.synchronizedList(new ArrayList<>());
			for(SupplyPlanVersionDetail obj : lastList) {
				LocalDateTime supplyDateActual = obj.getSupplyDateActual() == null ? obj.getSupplyTimeVirtual() : obj.getSupplyDateActual();
				if(supplyDateActual != null) {
					int yearMonth = LocalDateTimeUtils.toIntYearMonth(Integer.parseInt(month.split("-")[0]), Integer.parseInt(month.split("-")[1]));
					int actualYearMonth = LocalDateTimeUtils.toIntYearMonth(supplyDateActual.getYear(),supplyDateActual.getMonthValue());
					if(actualYearMonth < yearMonth) {
						versionId = obj.getVersionId();
						monthOverIds.add(obj.getOrgFullPathName());
					}
				}
			}
			if(CollectionUtils.isNotEmpty(monthOverIds)) {
				list = supplyPlanVersionDetailMapper.selectByVersionId(versionId, IsDeleteEnum.NO.getKey());
			}
			
			for(String str : monthOverIds) { 
				List<SupplyPlanVersionDetail> childList = getSelfAndChildData(lastList,str);
				for(SupplyPlanVersionDetail childObj : childList) {
					for(SupplyPlanVersionDetail resData : lastList) {
						if(resData.getId().equals(childObj.getId())) {
							SupplyPlanVersionDetail obj  = getSupplyPlanVersionDetail(list,resData.getId()); 
							if(obj != null) {
								if(obj.getIsParking() != null && obj.getIsParking().intValue() == 1) {
									resData.setParkingNum(obj.getParkingNum());
									resData.setNotCommodityValue(obj.getNotCommodityValue());
									resData.setAveragePriceParking(StrUtils.divide(obj.getNotCommodityValue(),obj.getParkingNum() == null ? BigDecimal.ZERO : new BigDecimal(obj.getParkingNum())));
								}else {
									resData.setRoomNum(obj.getRoomNum());
									resData.setHouseCommodityValue(obj.getHouseCommodityValue());
									resData.setSaleArea(obj.getSaleArea());
									resData.setAveragePriceHouse(StrUtils.divide(obj.getHouseCommodityValue(),obj.getSaleArea()));
								}
							}
						}
					}
				}
			}
			return lastList;
		}
		return dataList;
	}
	
	private SupplyPlanVersionDetail getSupplyPlanVersionDetail(List<SupplyPlanVersionDetail> list, String id) {
		if(CollectionUtils.isNotEmpty(list)) {
			for(SupplyPlanVersionDetail detail : list) {
				if(detail.getId().equals(id)) {
					return detail;
				}
			}
		}
		return null;
	}
	
	private List<SupplyPlanVersionDetail> getSelfAndChildData(List<SupplyPlanVersionDetail> list, String orgFullPath) {
		List<SupplyPlanVersionDetail> resList = Collections.synchronizedList(new ArrayList<>());
		if(CollectionUtils.isNotEmpty(list)) {
			for(SupplyPlanVersionDetail detail : list) {
				String type = detail.getType();
				if(type.equals(OrgTypeEunm.ORG_NOT_SALING_PARKING.getKey())) {
					continue;
				}
				if(detail.getOrgFullPathName().contains(orgFullPath)) {
					resList.add(detail);
				}
			}
		}
		return resList;
	}
	
	
	//处理显示数据（经营方式为可租和不可租售数据不显示）
	private void handleShowData(List<SupplyPlanVersionDetail> resdataList,List<SupplyPlanVersionDetail> lastList) {
		for(SupplyPlanVersionDetail supplyPlanVersionDetail : resdataList) {
			String businessTypeName = supplyPlanVersionDetail.getBusinessTypeName();
			if(StrUtils.isEmpty(businessTypeName)) {
				//判断是否有子级
				boolean flag = hasChild(resdataList,supplyPlanVersionDetail.getId());
				if(flag) {
					//子级经营方式是否都是可租或不可租售 ，是不显示，不是显示
					if(isShow(resdataList,supplyPlanVersionDetail.getId())) {
						lastList.add(supplyPlanVersionDetail);
					}
				}
			}else if(businessTypeName.equals(SalyTypeEnum.SALABLE.getValue()) || businessTypeName.equals(SalyTypeEnum.STAGE_SELF_SUSTAINMENT.getValue())){
				lastList.add(supplyPlanVersionDetail);
			}
		}
	}
	
	private void emptyData(List<SupplyPlanVersionDetail> resdataList) {
		for(SupplyPlanVersionDetail obj : resdataList) {
			if(hasChild(resdataList,obj.getId())) {
				obj.setNum(null);
				obj.setRoomNum(null);
				obj.setParkingNum(null);
				obj.setCommodityValue(null);
				obj.setHouseCommodityValue(null);
				obj.setNotCommodityValue(null);
				obj.setAveragePrice(null);
				obj.setAveragePriceParking(null);
				obj.setAveragePriceHouse(null);
				obj.setSaleArea(null);
				obj.setRoomNumActual(null);
				obj.setParkingNumActual(null);
				obj.setAreaActual(null);
				obj.setAveragePriceHouseActual(null);
				obj.setAveragePriceParkingActual(null);
				obj.setHouseCommodityValueActual(null);
				obj.setNotCommodityValueActual(null);
				obj.setCommodityValueActual(null);
			}
		}
	}
	
	private boolean hasChild(List<SupplyPlanVersionDetail> list,String id) {
		boolean flag = false;
		for(SupplyPlanVersionDetail supplyPlanVersionDetail : list) {
			String pid = supplyPlanVersionDetail.getPid();
			if(pid.equals(id)) {
				flag = true;
				break;
			}
		}
		return  flag;
	}
	
	private boolean isShow(List<SupplyPlanVersionDetail> list,String id) {
		boolean flag = false;
		for(SupplyPlanVersionDetail supplyPlanVersionDetail : list) {
			String pid = supplyPlanVersionDetail.getPid();
			String businessTypeName = supplyPlanVersionDetail.getBusinessTypeName();
			if(pid.equals(id)) {
				if(StrUtils.isEmpty(businessTypeName) || isValid(businessTypeName)) {
					flag = true;
					break;
				}
			}
		}
		return  flag;
	}
	
	private boolean isValid(String businessTypeName) {
		return businessTypeName.equals(SalyTypeEnum.SALABLE.getValue()) || businessTypeName.equals(SalyTypeEnum.STAGE_SELF_SUSTAINMENT.getValue());
	}

	SumValueVO sumVo = new SumValueVO(); 
	Map<String, SumValueVO> baseSumMap = new HashMap<>();
	private List<SupplyPlanVersionDetail> collectData(List<SupplyPlanVersionDetail> list) {
		//1、数据汇总
		for(SupplyPlanVersionDetail supplyPlanVersionDetail : list) {
			String id = supplyPlanVersionDetail.getId();
			boolean hasChild = hasChild(list,id);
			if(hasChild) {
				SumValueVO sum = buildDataTree(list,id,new SumValueVO());
				baseSumMap.put(id,sum);
				sumVo = new SumValueVO();
			}
		}
		
		//2、保存汇总的值
		for(Map.Entry<String,SumValueVO> entry : baseSumMap.entrySet()) {
			 String key = entry.getKey();
			 SumValueVO value = entry.getValue();
			 for(SupplyPlanVersionDetail supplyPlanVersionDetail : list) {
	            	if(supplyPlanVersionDetail.getId().equals(key)) {
	            		//面积
	            		supplyPlanVersionDetail.setSaleArea(value.getSumArea());
	            		//套数（非车位/车位）
	            		supplyPlanVersionDetail.setRoomNum(value.getSumRoomNum());
	            		supplyPlanVersionDetail.setParkingNum(value.getSumParkingNum());
	            		//金额（非车位/车位）
	            		supplyPlanVersionDetail.setHouseCommodityValue(value.getSumHouseCommodityValue());
	            		supplyPlanVersionDetail.setNotCommodityValue(value.getSumNotCommodityValue());
	            		supplyPlanVersionDetail.setCommodityValue(value.getSumValue());
	            		
	            		supplyPlanVersionDetail.setAreaActual(value.getSumAreaActual());
	            		supplyPlanVersionDetail.setRoomNumActual(value.getSumRoomNumActual());
	            		supplyPlanVersionDetail.setParkingNumActual(value.getSumParkingNumActual());
	            		supplyPlanVersionDetail.setHouseCommodityValueActual(value.getSumHouseCommodityValueActual());
	            		supplyPlanVersionDetail.setNotCommodityValueActual(value.getSumNotCommodityValueActual());
	            		supplyPlanVersionDetail.setCommodityValueActual(value.getSumValueActual());
	            	}
	            }
		}
		
		return list;
	}

	private SumValueVO buildDataTree(List<SupplyPlanVersionDetail> list, String parentId,SumValueVO vo) {
		for(SupplyPlanVersionDetail supplyPlanVersionDetail : list) {
			String id = supplyPlanVersionDetail.getId();
			String pid = supplyPlanVersionDetail.getPid();
			String businessTypeName = supplyPlanVersionDetail.getBusinessTypeName();
			Integer isParking = supplyPlanVersionDetail.getIsParking();
			
			//计划
			BigDecimal area = supplyPlanVersionDetail.getSaleArea()== null?BigDecimal.ZERO:supplyPlanVersionDetail.getSaleArea();
			Integer roomNum = supplyPlanVersionDetail.getRoomNum()== null?0:supplyPlanVersionDetail.getRoomNum();
			Integer parkingNum = supplyPlanVersionDetail.getParkingNum()== null?0:supplyPlanVersionDetail.getParkingNum();
			BigDecimal houseCommodityValue = supplyPlanVersionDetail.getHouseCommodityValue() == null?BigDecimal.ZERO:supplyPlanVersionDetail.getHouseCommodityValue();
			BigDecimal notCommodityValue = supplyPlanVersionDetail.getNotCommodityValue() == null?BigDecimal.ZERO:supplyPlanVersionDetail.getNotCommodityValue();
			BigDecimal commodityValue = supplyPlanVersionDetail.getCommodityValue() == null ? BigDecimal.ZERO:supplyPlanVersionDetail.getCommodityValue();
			
			//实际
			BigDecimal areaActual = supplyPlanVersionDetail.getAreaActual()==null?BigDecimal.ZERO:supplyPlanVersionDetail.getAreaActual();
			Integer roomNumActual = supplyPlanVersionDetail.getRoomNumActual()==null?0:supplyPlanVersionDetail.getRoomNumActual();
			Integer parkingNumActual =supplyPlanVersionDetail.getParkingNumActual()==null?0:supplyPlanVersionDetail.getParkingNumActual();
			BigDecimal houseCommodityValueActual = supplyPlanVersionDetail.getHouseCommodityValueActual()==null?BigDecimal.ZERO:supplyPlanVersionDetail.getHouseCommodityValueActual();
			BigDecimal notCommodityValueActual = supplyPlanVersionDetail.getNotCommodityValueActual()==null?BigDecimal.ZERO:supplyPlanVersionDetail.getNotCommodityValueActual();
			BigDecimal commodityValueActual = supplyPlanVersionDetail.getCommodityValueActual() == null ? BigDecimal.ZERO:supplyPlanVersionDetail.getCommodityValueActual();
			//车位数据 可售面积不累加
			if(isParking!= null && isParking.intValue() == 1) {
				area = BigDecimal.ZERO;
				areaActual = BigDecimal.ZERO;
			}
			if(parentId.equals(pid)) {

				if(StrUtils.isEmpty(businessTypeName) || isValid(businessTypeName)) {
					//计划
					BigDecimal sumArea = area.add(vo.getSumArea());
					Integer sumRoomNum = roomNum + vo.getSumRoomNum();
					Integer sumParkingNum = parkingNum + vo.getSumParkingNum();
					BigDecimal sumHouseCommodityValue = houseCommodityValue.add(vo.getSumHouseCommodityValue());
					BigDecimal sumNotCommodityValue = notCommodityValue.add(vo.getSumNotCommodityValue());
					BigDecimal sumCommodityValue = commodityValue.add(vo.getSumValue());
				
					//实际
					BigDecimal sumAreaActual = areaActual.add(vo.getSumAreaActual());
					Integer sumRoomNumActual = roomNumActual + vo.getSumRoomNumActual();
					Integer sumParkingNumActual = parkingNumActual + vo.getSumParkingNumActual();
					BigDecimal sumHouseCommodityValueActual = houseCommodityValueActual.add(vo.getSumHouseCommodityValueActual());
					BigDecimal sumNotCommodityValueActual = notCommodityValueActual.add(vo.getSumNotCommodityValueActual());
					BigDecimal sumCommodityValueActual = commodityValueActual.add(vo.getSumValueActual());
					
					//计划
					vo.setSumArea(sumArea);
					vo.setSumRoomNum(sumRoomNum);
					vo.setSumParkingNum(sumParkingNum);
					vo.setSumHouseCommodityValue(sumHouseCommodityValue);
					vo.setSumNotCommodityValue(sumNotCommodityValue);
					vo.setSumValue(sumCommodityValue);
					//实际
					vo.setSumAreaActual(sumAreaActual);
					vo.setSumRoomNumActual(sumRoomNumActual);
					vo.setSumParkingNumActual(sumParkingNumActual);
					vo.setSumHouseCommodityValueActual(sumHouseCommodityValueActual);
					vo.setSumNotCommodityValueActual(sumNotCommodityValueActual);
					vo.setSumValueActual(sumCommodityValueActual);
					buildDataTree(list,id,vo);
					
					//计划
					sumVo.setSumArea(vo.getSumArea());
					sumVo.setSumRoomNum(vo.getSumRoomNum());
					sumVo.setSumParkingNum(vo.getSumParkingNum());
					sumVo.setSumHouseCommodityValue(vo.getSumHouseCommodityValue());
					sumVo.setSumNotCommodityValue(vo.getSumNotCommodityValue());
					sumVo.setSumValue(vo.getSumValue());
					//实际
					sumVo.setSumAreaActual(vo.getSumAreaActual());
					sumVo.setSumRoomNumActual(vo.getSumRoomNumActual());
					sumVo.setSumParkingNumActual(vo.getSumParkingNumActual());
					sumVo.setSumHouseCommodityValueActual(vo.getSumHouseCommodityValueActual());
					sumVo.setSumNotCommodityValueActual(vo.getSumNotCommodityValueActual());
					sumVo.setSumValueActual(vo.getSumValueActual());
				}
			}
		}
		return sumVo;
	}
	
	public List<SupplyPlanVersionDetail> handleInvestment(List<SupplyPlanVersionDetail> versionDetailList) {
		List<SupplyPlanVersionDetail> resList =  Collections.synchronizedList(new ArrayList<>());
		List<SupplyPlanVersionDetail> productList =  Collections.synchronizedList(new ArrayList<>());
		List<SupplyPlanVersionDetail> batchList =  Collections.synchronizedList(new ArrayList<>());
		List<SupplyPlanVersionDetail> buildList =  Collections.synchronizedList(new ArrayList<>());
		Map<String, String> bMap = new HashMap<String, String>();
		Map<String, String> pMap = new HashMap<String, String>();
		
		for(SupplyPlanVersionDetail detail : versionDetailList) {
			 if(detail.getType().equals(OrgTypeEunm.ORG_PRODUCT.getKey())) {
				 detail.setOrgNames(detail.getOrgName()+"-"+detail.getBusinessTypeName()+"-"+detail.getFreeTypeName()+"-"+detail.getProTypeName());
				 pMap.put(detail.getId(), detail.getPid());
				 productList.add(detail);
			 }else if(detail.getType().equals(OrgTypeEunm.ORG_BATCH.getKey())){
				 bMap.put(detail.getId(), detail.getPid());
				 batchList.add(detail);
			 }else if(detail.getType().equals(OrgTypeEunm.ORG_STAGE.getKey()) || detail.getType().equals(OrgTypeEunm.ORG_GROUP.getKey())) {
				 resList.add(detail);
			 }
		}
		
		for(SupplyPlanVersionDetail product : productList) {
			for(Map.Entry<String, String> entry : bMap.entrySet()){
	            if(entry.getKey().equals(product.getPid())) {
	            	product.setPid(entry.getValue());
	            }
	        }
		}
		
		for(SupplyPlanVersionDetail product : productList) {
			for(Map.Entry<String, String> entry : pMap.entrySet()){
	            if(entry.getKey().equals(product.getId())) {
	            	for(SupplyPlanVersionDetail batch :batchList ) {
	            		if(batch.getId().equals(entry.getValue())) {
	            			SupplyPlanVersionDetail obj = new SupplyPlanVersionDetail();
	            			obj.setId(UUIDUtils.create());
	            			obj.setOrgId(batch.getOrgId());
	            			obj.setOrgCode(batch.getOrgCode());
	            			obj.setOrgName(batch.getOrgName());
	            			obj.setType(OrgTypeEunm.ORG_BUILD.getKey());
	            			obj.setPid(product.getId());
	            			obj.setIsParking(product.getIsParking());
	            			obj.setSupplyDate(product.getSupplyDate());
	            			obj.setSupplyDateActual(product.getSupplyDateActual());
	            			obj.setSupplyTimeVirtual(product.getSupplyTimeVirtual());
	            			
	            			obj.setBusinessType(product.getBusinessType());
	            			obj.setBusinessTypeName(product.getBusinessTypeName());
	            			
	            			obj.setFreeType(product.getFreeType());
	            			obj.setFreeTypeName(product.getFreeTypeName());
	            			
	            			obj.setProType(product.getProType());
	            			obj.setProTypeName(product.getProTypeName());
	            			
	            			obj.setRoomNum(product.getRoomNum());
	            			obj.setParkingNum(product.getParkingNum());
	            			obj.setForsaleParkingNum(product.getForsaleParkingNum());
	            			obj.setSaleArea(product.getSaleArea());
	            			obj.setHouseCommodityValue(product.getHouseCommodityValue());
	            			obj.setNotCommodityValue(product.getNotCommodityValue());
	            			obj.setCommodityValue(product.getCommodityValue());
	            			
	            			buildList.add(obj);
	            		}
	            	}
	            	
	            }
	        }
		}
		resList.addAll(productList);
		resList.addAll(buildList);
		setSupplyOrgFullpath(resList,Constants.ROOT_NODE_PID);
		
		List<SupplyPlanVersionDetail> uniqResList = resList.stream().collect(
                Collectors.collectingAndThen(
                        Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(SupplyPlanVersionDetail::getOrgFullPathName))), ArrayList::new)
        );
		
		Map<String, String> map = new HashMap<>();
		
		for(SupplyPlanVersionDetail obj : uniqResList) {
			if(obj.getType().equals(OrgTypeEunm.ORG_PRODUCT.getKey())) {
				map.put(obj.getOrgFullPathName(), obj.getId());
			}
		}
		
		for(SupplyPlanVersionDetail obj : uniqResList) {
			if(obj.getType().equals(OrgTypeEunm.ORG_BUILD.getKey())) {
				String fullPathName = obj.getOrgFullPathName();
				for(Map.Entry<String, String> entry : map.entrySet()){
					if(fullPathName.contains(entry.getKey())) {
						obj.setPid(entry.getValue());
					}
				}
			}
		}
		
		return uniqResList;
	}
	
	/***
	 * 
	 * @Description：设置全路径
	 * @author：yyd
	 * @date：2020年2月25日 下午2:32:43
	 */
	private List<SupplyPlanVersionDetail> setSupplyOrgFullpath(List<SupplyPlanVersionDetail> supplyPlanValueOrgList, String pid) {
		String fullPath ="";
		String fullPathName = "";
		for(SupplyPlanVersionDetail org : supplyPlanValueOrgList) {
			if(org.getId().equals(pid)) {
				fullPath= org.getOrgFullPath();
				fullPathName = org.getOrgFullPathName();
			}
		}
		for(SupplyPlanVersionDetail org : supplyPlanValueOrgList) {
			if(org.getPid().equals(pid)) {
				if(org.getType().equals(OrgTypeEunm.ORG_PRODUCT.getKey())) {
					org.setOrgFullPath(fullPath+"/"+org.getProProductCode()+"/"+org.getOrgCode());
					org.setOrgFullPathName(fullPathName+"/"+org.getProProductType()+"/"+org.getOrgName());
				}else {
					org.setOrgFullPath(fullPath+"/"+org.getOrgCode());
					org.setOrgFullPathName(fullPathName+"/"+org.getOrgName());
				}
				setSupplyOrgFullpath(supplyPlanValueOrgList,org.getId());
			}
		}
		return supplyPlanValueOrgList;
	}
	

}
